package com.alvis.media.service.impl;

import com.alvis.media.domain.VideoInfo;
import com.alvis.media.domain.VideoPlay;
import com.alvis.media.repository.MediaBaseMapper;
import com.alvis.media.repository.VideoInfoMapper;
import com.alvis.media.repository.VideoPlayMapper;
import com.alvis.media.service.VideoInfoService;
import com.alvis.media.utility.DateTimeUtil;
import com.alvis.media.utility.UserCFUtil;
import com.alvis.media.viewmodel.video.VideoPageRequestVM;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 奇趣
 */
@Service

public class VideoInfoServiceImpl extends BaseServiceImpl <VideoInfo> implements VideoInfoService {


    private final VideoInfoMapper videoInfoMapper;
    private final VideoPlayMapper videoPlayMapper;


    @Autowired
    public VideoInfoServiceImpl(VideoInfoMapper videoInfoMapper, VideoPlayMapper videoPlayMapper, MediaBaseMapper<VideoInfo> videoInfoMapperr) {
        super(videoInfoMapperr);
        this.videoInfoMapper = videoInfoMapper;
        this.videoPlayMapper = videoPlayMapper;

    }

    @Override
    public int insertByFilter(VideoInfo record) {
        record.setLastModifyTime(new Date());
        record.setCreateTime(new Date());
        return baseMapper.insertSelective(record);
    }

    @Override
    public int selectNewVideoCount(VideoInfo filter) {
        //当月的用户新增视频数量
        //封装查询条件
        filter.setCreateTime(DateTimeUtil.getMonthStartDay());
        // 调用dao 并返回
        return videoInfoMapper.selectNewVideoCount(filter);
    }

    @Override
    public PageInfo <VideoInfo> userPage(VideoPageRequestVM requestVM) {
        return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "video_id desc").doSelectPageInfo(() ->
                videoInfoMapper.videoPage(requestVM)
        );
    }

    @Override
    public List <VideoInfo> userAnalysis(Integer recommendUserId) {
        // 检查参数
        if (recommendUserId == null) {
            return videoInfoMapper.selectHotVideoList();
        }

        List <VideoInfo> result = new ArrayList<>();
        //和该推荐用户的播放记录有交集的用户的播放记录。
        //第一步查找recommendUserId的播放列表 userid
        //要求推荐的用户播放的视频id列表
        List <Integer> recommendVideoIdPlayList = getPlayVideoIdListByUserId(recommendUserId);
        if (org.springframework.util.CollectionUtils.isEmpty(recommendVideoIdPlayList)) {
            return videoInfoMapper.selectHotVideoList();
        }

        Set<Integer> relationUserIdList = new HashSet <>();
        //遍历recommendVideoIdPlayList 去查找播放过这些视频的用户
        for (Integer videoId : recommendVideoIdPlayList) {
            VideoPlay filter = new VideoPlay();

            filter.setVideoId(videoId);
            List <VideoPlay> otherUserPlayList = videoPlayMapper.selectVideoPlayInfo(filter);

            if (org.springframework.util.CollectionUtils.isEmpty(otherUserPlayList)) {
                continue;
            }
            relationUserIdList.addAll(otherUserPlayList.stream()
                    .map(e -> e.getUserId()).collect(Collectors.toSet()));
        }

        //和该推荐用户的播放记录有交集的用户的播放记录。
        Map<Integer, List <Integer>> playList = new HashMap <>();
        playList.put(recommendUserId, recommendVideoIdPlayList);

        for (Integer userId : relationUserIdList) {
            if (userId.equals(recommendUserId)) {
                continue;
            }
            //要求推荐的用户播放的视频id列表
            playList.put(userId, getPlayVideoIdListByUserId(userId));
        }

        List <Integer> recommendVideoIdList = UserCFUtil.getRecommendationVideoList(playList, recommendUserId);
        //如果没有可推荐的
        if(org.springframework.util.CollectionUtils.isEmpty(recommendVideoIdList))
        {
            return  videoInfoMapper.selectHotVideoList();
        }
        
        // 根据推荐的视频ID列表获取视频信息
        for (Integer videoId : recommendVideoIdList) {
            VideoInfo videoInfo = videoInfoMapper.selectByPrimaryKey(videoId);
            if (videoInfo != null) {
                result.add(videoInfo);
            }
        }
        
        // 如果推荐结果为空，返回热门视频
        if (result.isEmpty()) {
            return videoInfoMapper.selectHotVideoList();
        }
        
        return result;
    }

    private List <Integer> getPlayVideoIdListByUserId(Integer userId) {
        VideoPlay filter = new VideoPlay();
        filter.setUserId(userId);
        List <VideoPlay> recommendUserPlayList = videoPlayMapper.selectVideoPlayInfo(filter);
        //如果没有播放列表，则没有推荐产品
        if (org.springframework.util.CollectionUtils.isEmpty(recommendUserPlayList)) {
            return new ArrayList <>();
        }
        //要求推荐的用户播放的视频id列表
        List <Integer> recommendVideoIdPlayList = recommendUserPlayList.stream()
                .map(e -> e.getVideoId()).collect(Collectors.toList());

        return recommendVideoIdPlayList;
    }

    @Override
    public int insertVideoPlay(String realUrl, Integer userId) {
        // 检查参数
        if (realUrl == null || userId == null) {
            return 0;
        }
        
        // 根据视频URL获取视频ID
        Integer videoId = videoInfoMapper.selectVideoIdByUrl(realUrl);
        if (videoId == null) {
            return 0;
        }
        
        // 创建视频播放记录查询条件
        VideoPlay filter = new VideoPlay();
        filter.setUserId(userId);
        filter.setVideoId(videoId);
        
        // 查询用户是否已经播放过该视频
        List <VideoPlay> videoPlayListDb = videoPlayMapper.selectVideoPlayInfo(filter);
        VideoPlay videoPlay = new VideoPlay();
        videoPlay.setUserId(userId);
        videoPlay.setVideoId(videoId);
        videoPlay.setLastPlayTime(new Date());
        
        if (CollectionUtils.isEmpty(videoPlayListDb)) {
            // 如果没有播放记录，则插入新记录
            videoPlay.setPlayTimes(1);
            videoPlayMapper.insertSelective(videoPlay);
        } else {
            // 如果已有播放记录，则更新播放次数和最后播放时间
            VideoPlay videoPlayDb = videoPlayListDb.get(0);
            videoPlay.setPlayTimes(videoPlayDb.getPlayTimes() + 1);
            videoPlayMapper.updateByPrimaryKeySelective(videoPlay);
        }

        return 1;
    }
}